package com.xiaoshuidi.cloud.module.bpm.convert.swo;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.xiaoshuidi.cloud.framework.common.util.json.JsonUtils;
import com.xiaoshuidi.cloud.module.bpm.controller.admin.swo.vo.SwoTicketExcelVO;
import com.xiaoshuidi.cloud.module.bpm.dal.dataobject.swo.SwoTicketDO;
import com.xiaoshuidi.cloud.module.bpm.dal.dataobject.sworecord.SwoTicketAssignRecordDO;
import com.xiaoshuidi.cloud.module.bpm.enums.MaintenanceFlagEnum;
import com.xiaoshuidi.cloud.module.bpm.enums.swo.*;
import com.xiaoshuidi.cloud.module.bpm.service.sworecord.SwoTicketAssignRecordService;
import com.xiaoshuidi.cloud.module.contract.api.ContractRentOrderApi;
import com.xiaoshuidi.cloud.module.contract.vo.GetSowTicketOrderByIdsReq;
import com.xiaoshuidi.cloud.module.contract.vo.RentOrderSowTicketVO;
import com.xiaoshuidi.cloud.module.rooms.api.apartment.ApartmentApi;
import com.xiaoshuidi.cloud.module.rooms.api.apartment.dto.ApartmentListDto;
import com.xiaoshuidi.cloud.module.system.api.user.AdminUserApi;
import com.xiaoshuidi.cloud.module.system.api.user.dto.AdminUserRespDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class MySwoTicketConvert {

    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private ApartmentApi apartmentApi;
    @Resource
    private SwoTicketAssignRecordService swoTicketAssignRecordService;
    @Resource
    private ContractRentOrderApi contractRentOrderApi;

    public List<SwoTicketExcelVO> convert(List<SwoTicketDO> list) {
        if ( ObjectUtil.isEmpty(list) ) {
            return null;
        }
        int flag = 100;

        List<SwoTicketExcelVO> list1 = new ArrayList<SwoTicketExcelVO>( list.size() );
        List<Long> assigneeList = list.stream().filter(p -> ObjectUtil.isNotEmpty(p.getAssignee())).map(SwoTicketDO::getAssignee).distinct().collect(Collectors.toList());
        Map<Long, AdminUserRespDTO> userMap = new HashMap<>();
        extracted(assigneeList, flag, userMap);
        log.info("服务工单导出, 跟进人信息:{}", JsonUtils.toJsonString(userMap));
        List<Long> apartmentIds = list.stream().filter(p -> ObjectUtil.isNotEmpty(p.getApartmentId())).map(SwoTicketDO::getApartmentId).distinct().collect(Collectors.toList());
        List<ApartmentListDto> apartmentListDtos = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(apartmentIds)) {
            apartmentListDtos = apartmentApi.listByIds(apartmentIds).getCheckedData();
        }
        Map<Long, String> apartmentMap = apartmentListDtos.stream().collect(Collectors.toMap(ApartmentListDto::getId, ApartmentListDto::getName));
        // 所有服务工单的指派记录
        List<Long> swoTicketIds = list.stream().map(SwoTicketDO::getId).collect(Collectors.toList());
        List<SwoTicketAssignRecordDO> assignmentRecordByIds = swoTicketAssignRecordService.getAssignmentRecordByIds(swoTicketIds);
        Map<Long, SwoTicketAssignRecordDO> swoTicketAssignRecordMap = new HashMap<>();
        if(ObjectUtil.isNotEmpty(assignmentRecordByIds)){
            swoTicketAssignRecordMap = assignmentRecordByIds.stream().collect(Collectors.toMap(SwoTicketAssignRecordDO::getSwoTicketId, o -> o));
        }
        // 所有工单首次受理人
        List<Long> assignmentIds = assignmentRecordByIds.stream().map(SwoTicketAssignRecordDO::getAssignee).collect(Collectors.toList());
        Map<Long, AdminUserRespDTO> assignmentMap = new HashMap<>();
        if(ObjectUtil.isNotEmpty(assignmentIds)){
            extracted(assignmentIds, flag, assignmentMap);
        }

        // 所有工单的创建人
        List<Long> creators = list.stream().filter(p -> ObjectUtil.isNotEmpty(p.getCreator())).map(p -> Long.valueOf(p.getCreator())).distinct().collect(Collectors.toList());
        Map<Long, AdminUserRespDTO> creatorMap = new HashMap<>();
        if(ObjectUtil.isNotEmpty(creators)){
            extracted(creators, flag, creatorMap);
        }
        // 所有工单的账单信息
        Map<Long, List<RentOrderSowTicketVO>> swoTicketRentOrderMap = contractRentOrderApi.getSowTicketOrderByIds(new GetSowTicketOrderByIdsReq().setSwoTicketIds(swoTicketIds)).getCheckedData();
        for ( SwoTicketDO swoTicketDO : list ) {
            list1.add( swoTicketDOToSwoTicketExcelVO( swoTicketDO, userMap, apartmentMap, swoTicketAssignRecordMap, creatorMap, swoTicketRentOrderMap, assignmentMap) );
        }

        return list1;
    }

    private void extracted(List<Long> creators, int flag, Map<Long, AdminUserRespDTO> creatorMap) {
        for (int i = 0; i <= creators.size() / flag; i++) {
            List<Long> ids = new ArrayList<>();
            if(i< creators.size()/ flag){
                ids = creators.subList(i * flag, (i + 1) * flag);
            }else {
                ids = creators.subList(i * flag, creators.size());
            }
            creatorMap.putAll(adminUserApi.getUserMap(ids));
        }
    }

    private SwoTicketExcelVO swoTicketDOToSwoTicketExcelVO(SwoTicketDO swoTicketDO, Map<Long, AdminUserRespDTO> userMap, Map<Long, String> apartmentMap, Map<Long, SwoTicketAssignRecordDO> swoTicketAssignRecordMap, Map<Long, AdminUserRespDTO> creatorMap, Map<Long, List<RentOrderSowTicketVO>> swoTicketRentOrderMap, Map<Long, AdminUserRespDTO> assignmentMap) {
        if ( swoTicketDO == null ) {
            return null;
        }
        SwoTicketExcelVO swoTicketExcelVO = new SwoTicketExcelVO();
        swoTicketExcelVO.setRoomFullName(swoTicketDO.getRoomFullName());

        AdminUserRespDTO adminUserRespDTO = new AdminUserRespDTO();
        if(ObjectUtil.isNotEmpty(swoTicketDO.getAssignee())){
            adminUserRespDTO = userMap.get(swoTicketDO.getAssignee());
        }
        if(ObjectUtil.isNotEmpty(swoTicketDO.getApartmentId())){
            swoTicketExcelVO.setApartmentName(apartmentMap.get(swoTicketDO.getApartmentId()));
        }
        swoTicketExcelVO.setMaintenanceFlag(MaintenanceFlagEnum.getNameByValue(swoTicketDO.getMaintenanceFlag()));
        swoTicketExcelVO.setCustomerName( swoTicketDO.getCustomerName() );
        swoTicketExcelVO.setCustomerMobile( swoTicketDO.getCustomerMobile() );
        swoTicketExcelVO.setSource(TicketSourceEnum.getNameByValue(swoTicketDO.getSource()) );
        swoTicketExcelVO.setServiceType(SwoServiceTypeEnum.getNameByValue(swoTicketDO.getServiceType()));
        swoTicketExcelVO.setServiceTimeStart( swoTicketDO.getServiceTimeStart() );
        swoTicketExcelVO.setServiceTimeEnd( swoTicketDO.getServiceTimeEnd() );
        swoTicketExcelVO.setCompleteTime( swoTicketDO.getCompleteTime() );
        swoTicketExcelVO.setServiceTobeCompleted( swoTicketDO.getServiceTobeCompleted() );
        swoTicketExcelVO.setResponsibleParty(ResponsiblePartyEnum.getNameByValue(swoTicketDO.getResponsibleParty()) );
        swoTicketExcelVO.setTopic( swoTicketDO.getTopic() );
        swoTicketExcelVO.setContent( swoTicketDO.getContent() );
        swoTicketExcelVO.setAttachments( swoTicketDO.getAttachments() );
        swoTicketExcelVO.setAssigneeName( adminUserRespDTO.getNickname() );
        swoTicketExcelVO.setProcessStatus(TicketServiceProcessStatusEnum.getNameByStatus(swoTicketDO.getProcessStatus()) );
        swoTicketExcelVO.setCreateTime( swoTicketDO.getCreateTime() );
        swoTicketExcelVO.setRating(Integer.valueOf(0).equals(swoTicketDO.getRating()) ? null : swoTicketDO.getRating());
        swoTicketExcelVO.setComments(swoTicketDO.getComments());
        swoTicketExcelVO.setWoNumber(swoTicketDO.getWoNumber());
        // 第一次受理时间
        swoTicketExcelVO.setFirstAssignmentTime(ObjectUtil.isNotEmpty(swoTicketAssignRecordMap.get(swoTicketDO.getId())) ? swoTicketAssignRecordMap.get(swoTicketDO.getId()).getCreateTime() : null);
        swoTicketExcelVO.setActualProcessingTime(swoTicketDO.getActualProcessingTime());
        // 受理人
        if(ObjectUtil.isNotEmpty(swoTicketAssignRecordMap.get(swoTicketDO.getId()))){
            AdminUserRespDTO userRespDTO = assignmentMap.get(swoTicketAssignRecordMap.get(swoTicketDO.getId()).getAssignee());
            if(ObjectUtil.isNotEmpty(userRespDTO)){
                swoTicketExcelVO.setAcceptee(userRespDTO.getNickname());
            }
        }
        swoTicketExcelVO.setRepairType(SwoTicketRepairTypeEnum.getNameByValue(swoTicketDO.getRepairType()));
        if(ObjectUtil.isNotEmpty(swoTicketDO.getCreator())){
            swoTicketExcelVO.setCreator(ObjectUtil.isNotEmpty(creatorMap.get(Long.valueOf(swoTicketDO.getCreator()))) ? creatorMap.get(Long.valueOf(swoTicketDO.getCreator())).getNickname() : null);
        }
        // 账单信息
        List<RentOrderSowTicketVO> rentOrderSowTicketVOS = swoTicketRentOrderMap.get(swoTicketDO.getId());
        if(ObjectUtil.isNotEmpty(rentOrderSowTicketVOS)){
            // 存在账单信息， 则是有偿维修
            swoTicketExcelVO.setNeedPay("是");
            BigDecimal decimal = BigDecimal.ZERO;
            // 统计所有账单总金额
            for (RentOrderSowTicketVO rentOrderSowTicketVO : rentOrderSowTicketVOS) {
                decimal = decimal.add(rentOrderSowTicketVO.getTotalAmount());
            }
            swoTicketExcelVO.setAmountOfRepairs(decimal);
        }else{
            swoTicketExcelVO.setNeedPay("否");
        }
        // 计算维修时长
        if(ObjectUtil.isNotEmpty(swoTicketDO.getCompleteTime())){
            long minutes = LocalDateTimeUtil.between(swoTicketDO.getCreateTime(), swoTicketDO.getCompleteTime()).toMinutes();
            BigDecimal divide = BigDecimal.valueOf(minutes).divide(BigDecimal.valueOf(60), 1, RoundingMode.HALF_UP);
            swoTicketExcelVO.setDurationOfRepairs(divide.toString());
        }

        return swoTicketExcelVO;
    }
}
